package com.itcast.java.product.controller;


import com.itcast.java.common.base.IdParam;
import com.itcast.java.common.base.R;
import com.itcast.java.product.dto.PmsCategoryDTO;
import com.itcast.java.product.entity.PmsCategoryEntity;
import com.itcast.java.product.service.IPmsCategoryService;
import com.itcast.java.product.vo.AddPmsCategoryVO;
import com.itcast.java.product.vo.UpdatePmsCategoryVO;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 商品三级分类前端控制器
 *
 * @author xiaobai
 * @date 2021-06-27 19:31:58
 */
@RestController
@RequestMapping("/product/category")
public class PmsCategoryController {

    @Autowired
    private IPmsCategoryService pmsCategoryService;
    @Autowired
    private ModelMapper modelMapper;

    /**
     * 算法：
     *  用MAP把所有的分类层级进行拆分，key分别为1、2、3...，然后MAP的value也是一个MAP，value的MAP保存ID跟分类对象的映射，通过向上和向下寻找对应的父子级关系，并通过children字段进行关联。
     *  方案1：
     *      KEY为当前映射的分类对象的ID，那么向上寻找时，可以快速找到当前分类的父级分类（根据当前分类的父级ID），向下寻找时，只能遍历所有的value值。
     *  方案2：
     *      KEY为当前映射的分类对象的父级ID，那么向上寻找时，只能遍历所的value值，向下寻找时 ，可以根据子类的父级ID快速找到其子类集合。
     *
     *   优化：
     *      sql查询分类列表时，根据层级排序（正、反），从而选择对应的方案，从而提高以上算法的效率。
     *
     * @return 返回关联了子类集合的顶级分类集合
     */
    @GetMapping("/tree")
    public R<List<PmsCategoryDTO>> tree() {
        List<PmsCategoryEntity> categories = pmsCategoryService.list();

        HashMap<Integer, Map<Long, PmsCategoryDTO>> levelToMap = new HashMap<>();
        PmsCategoryDTO pmsCategoryDTO = null;
        PmsCategoryDTO parentPmsCategoryDTO = null;
        Map<Long, PmsCategoryDTO> idToCategoryMap = null;
        for (PmsCategoryEntity category : categories) {
            // 是不是顶层
            if (category.getCatLevel() == 1) {
                idToCategoryMap = levelToMap.get(1);
                if (idToCategoryMap == null) {
                    idToCategoryMap = new HashMap<>();
                    levelToMap.put(1, new HashMap<>());
                }
                pmsCategoryDTO = modelMapper.map(category, PmsCategoryDTO.class);
                idToCategoryMap.put(pmsCategoryDTO.getCatId(), pmsCategoryDTO);
                idToCategoryMap = levelToMap.get(2);
                if (idToCategoryMap == null) {
                    continue;
                } else {
                    for (PmsCategoryDTO value : idToCategoryMap.values()) {
                        if (value.getParentCid().equals(category.getCatId())) {
                            List<PmsCategoryDTO> children = pmsCategoryDTO.getChildren();
                            if (children == null) {
                                LinkedList<PmsCategoryDTO> pmsCategoryDTOS = new LinkedList<>();
                                pmsCategoryDTOS.add(value);
                                pmsCategoryDTO.setChildren(pmsCategoryDTOS);
                            } else {
                                pmsCategoryDTO.getChildren().add(pmsCategoryDTO);
                            }
                        }

                    }
                }
                continue;
            }

            // 放入对应层级的map中
            pmsCategoryDTO = modelMapper.map(category, PmsCategoryDTO.class);
            idToCategoryMap = levelToMap.get(pmsCategoryDTO.getCatLevel());
            if (idToCategoryMap == null) {
                idToCategoryMap = new HashMap<>();
                idToCategoryMap.put(pmsCategoryDTO.getCatId(), pmsCategoryDTO);
                levelToMap.put(pmsCategoryDTO.getCatLevel(), idToCategoryMap);
            } else {
                idToCategoryMap.put(pmsCategoryDTO.getCatId(), pmsCategoryDTO);
            }

            // 查找对应父层级的集合
            idToCategoryMap = levelToMap.get(pmsCategoryDTO.getCatLevel()-1);
            if (idToCategoryMap == null) {
                continue;
            }
            parentPmsCategoryDTO = idToCategoryMap.get(pmsCategoryDTO.getParentCid());
            if (parentPmsCategoryDTO != null) {
                List<PmsCategoryDTO> children = parentPmsCategoryDTO.getChildren();
                if (children == null) {
                    LinkedList<PmsCategoryDTO> list = new LinkedList<>();
                    list.add(pmsCategoryDTO);
                    parentPmsCategoryDTO.setChildren(list);
                } else {
                    children.add(pmsCategoryDTO);
                }
            }

            // 查找子层级的集合
            idToCategoryMap = levelToMap.get(pmsCategoryDTO.getCatLevel()+1);
            if (idToCategoryMap == null) {
                continue;
            }
            List<PmsCategoryDTO> children = pmsCategoryDTO.getChildren();
            for (PmsCategoryDTO categoryDTO : idToCategoryMap.values()) {
                if (categoryDTO.getParentCid().equals(pmsCategoryDTO.getCatId())) {
                    if (children == null) {
                        LinkedList<PmsCategoryDTO> list = new LinkedList<>();
                        list.add(categoryDTO);
                        pmsCategoryDTO.setChildren(list);
                    } else {
                        children.add(categoryDTO);
                    }
                }
            }
        }

        return levelToMap.size() > 0 ? R.ok(new ArrayList<>(levelToMap.get(1).values())) : R.ok(Collections.emptyList());
    }

    @PostMapping("/delete")
    public R<Boolean> delete(@RequestBody IdParam<String> param) {
        pmsCategoryService.deleteById(param.getId());
        return R.ok(true);
    }

    @PostMapping("/add")
    public R<Boolean> add(@RequestBody AddPmsCategoryVO param) {
        pmsCategoryService.create(param);
        return R.ok(true);
    }

    @PostMapping("/update")
    public R<Boolean> update(@RequestBody UpdatePmsCategoryVO param) {
        pmsCategoryService.update(param);
        return R.ok(true);
    }

}
